package com.xiaoma.bingox.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.xiaoma.bingox.entity.Resource;
import com.xiaoma.bingox.entity.RoleResource;
import com.xiaoma.bingox.entity.User;
import com.xiaoma.bingox.service.ResourceService;
import com.xiaoma.bingox.utils.Bingox;
import com.xiaoma.bingox.vo.TreeNode;

@Controller
@RequestMapping("/app/resource")
public class ResourceController {

    @Autowired
    private ResourceService resourceService;
    
    @RequestMapping(method = RequestMethod.GET)
    public String index(){
        return "/resource/index";
    }
    
    @RequestMapping(value="/datas",method=RequestMethod.GET)
    @ResponseBody
    public Map<String,Object> datas(){
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("rows", resourceService.findAllVos());
        return result;
    }
    
    @RequestMapping(value="/save", method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> save(Resource resource){
        Map<String,Object> result = new HashMap<String, Object>();
        try {
            resourceService.save(resource);
            result.put("status", 1);
        } catch(Exception e) {
            result.put("status", 0);
        }
        return result;
    }
    
    @RequestMapping(value="/update", method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> update(Resource resource){
        Map<String,Object> result = new HashMap<String, Object>();
        try {
            resourceService.update(resource);
            result.put("status", 1);
        } catch(Exception e) {
            result.put("status", 0);
            result.put("message", e.getMessage());
        }
        return result;
    }
    
    @RequestMapping(value="/delete/{id}", method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> delete(@PathVariable Integer id){
        Map<String,Object> result = new HashMap<String, Object>();
        try {
            RoleResource entity = new RoleResource();
            entity.setResourceId(id);
            if (resourceService.findRoleResource(entity).size() == 0 && resourceService.findChildrenCount(id) == 0) {
                resourceService.delete(id);
                result.put("status", 1);
            } else {
                result.put("status", 0);
                result.put("message", "该资源被引用，无法删除");
                
            }
        } catch(Exception e) {
            result.put("status", 0);
            result.put("message", e.getMessage());
        }
        return result;
    }
    
    @RequestMapping(value="/treeMenu", method = RequestMethod.GET)
    @ResponseBody
    public JSONArray treeMenu(HttpSession session){
        User user = (User)session.getAttribute(Bingox.CURRENT_USER);
        RoleResource entity = new RoleResource();
        entity.setRoleId(user.getRoleId());
        List<RoleResource> roleResources = resourceService.findRoleResource(entity);
        
        List<Integer> resourceIds = new ArrayList<Integer>(roleResources.size());
        for (RoleResource item : roleResources) {
            resourceIds.add(item.getResourceId());
        }
        return buildTreeMenu(resourceIds);
        
    }
    
    @RequestMapping(value="/treeRole/{roleId}", method = RequestMethod.GET)
    @ResponseBody
    public JSONArray treeRole(@PathVariable Integer roleId){
        RoleResource entity = new RoleResource();
        entity.setRoleId(roleId);
        List<RoleResource> roleResources = resourceService.findRoleResource(entity);
        List<Integer> allocatedResourceIds = new ArrayList<Integer>(roleResources.size());
        for (RoleResource roleResource : roleResources) {
            allocatedResourceIds.add(roleResource.getResourceId());
        }
        List<Resource> resources = resourceService.findAll();
        return buildTree(resources, allocatedResourceIds);
        
    }
    
    private JSONArray buildTree(List<Resource> resources, List<Integer> allocatedResourceIds) {
        JSONArray jr = new JSONArray();
        if (resources.size() > 0) {
            Map<Integer, TreeNode> map = new HashMap<Integer, TreeNode>(resources.size());
            for (Resource r : resources) {
                TreeNode tn = new TreeNode();
                tn.setId(r.getId());
                tn.setText(r.getText());
                tn.getAttributes().setUrl(r.getUrl());
                tn.getAttributes().setParentId(r.getParentId());
                map.put(r.getId(), tn);
                if (r.getParentId() == null) {
                    jr.add(tn);
                }
                
                if (allocatedResourceIds.size() > 0 && allocatedResourceIds.contains(r.getId())) {//将已分配的节点置为checked
                    tn.setChecked(true);
                }
            }
            
            List<TreeNode> treeNodes = new ArrayList<TreeNode>(map.values());
            for (TreeNode node : treeNodes) {
                if (node.getAttributes().getParentId() != null) {
                    map.get(node.getAttributes().getParentId()).addChild(node);
                }
            }
        }
        return jr;
    }
    
    private JSONArray buildTreeMenu(List<Integer> resourceIds) {//先找到完整的resource链，再buildTree.
        List<Resource> relatedResources = new ArrayList<Resource>();
        if (resourceIds.size() > 0) {
            List<Resource> resources = resourceService.findAll();
            Map<Integer, Resource> map = new HashMap<Integer, Resource>(resources.size());
            for (Resource r : resources) {
                map.put(r.getId(),r);
            }
            
            for (Integer resourceId : resourceIds) {
                if (map.containsKey(resourceId)) {
                    Resource resource = map.get(resourceId);
                    relatedResources.add(resource);
                    map.remove(resource.getId());
                    while(resource.getParentId() != null && map.containsKey(resource.getParentId())){
                        resource = map.get(resource.getParentId());
                        relatedResources.add(resource);
                        map.remove(resource.getId());
                    }
                }
            }
            
        }
        return buildTree(relatedResources);
    }
    
    private JSONArray buildTree(List<Resource> resources) {//将一个完整的(从根节点一直到root节点不断)resources链，整理成为树结构
        JSONArray jr = new JSONArray();
        if (resources.size() > 0) {
            Map<Integer, TreeNode> map = new HashMap<Integer, TreeNode>(resources.size());
            for (Resource r : resources) {
                TreeNode tn = new TreeNode();
                tn.setId(r.getId());
                tn.setText(r.getText());
                tn.getAttributes().setUrl(r.getUrl());
                tn.getAttributes().setParentId(r.getParentId());
                map.put(r.getId(), tn);
                if (r.getParentId() == null) {
                    jr.add(tn);
                }
            }
            List<TreeNode> treeNodes = new ArrayList<TreeNode>(map.values());
            for (TreeNode node : treeNodes) {
                if (node.getAttributes().getParentId() != null) {
                    map.get(node.getAttributes().getParentId()).addChild(node);
                }
            }
        }
        return jr;
    }
}
